package com.fessc.develop.handler.processor.request;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fessc.develop.base.Result;
import com.fessc.develop.entity.KeyPropertiesVo;
import com.fessc.develop.entity.comvo.*;
import com.fessc.develop.entity.dbvo.TIdentityVerify;
import com.fessc.develop.entity.dbvo.TOrgUrlManage;
import com.fessc.develop.handler.SignHandler;
import com.fessc.develop.model.enums.*;
import com.fessc.develop.service.interfaces.ITIdentityVerifyService;
import com.fessc.develop.service.interfaces.ITOrgUrlManageService;
import com.fessc.develop.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class ComIdentityVerifyService implements IBaseService {

    @Resource
    private SignHandler signHandler;

    @Resource
    private ITOrgUrlManageService tOrgUrlManageService;

    @Resource
    private ITIdentityVerifyService identityVerifyService;

    @Resource
    private OkHttpUtil okHttpUtil;

    @Resource
    private KeyPropertiesVo keyPropertiesVo;

    @Override
    public String getServiceCode() {
        return EnumServiceCode.COM_BS0002.toString();
    }

    @Override
    public Result process(JSONObject request) {
        log.info("银行核验边民商铺备案查询请求报文: " + request.toJSONString());
        Result result = null;
        String errorCode = "";
        IdentityVerifyResVo identityVerifyResVo = new IdentityVerifyResVo();
        IdentityVerifyReqVo identityVerifyReqVo = JSON.parseObject(request.getJSONObject(EnumJsonProperty.REQ_BODY.toString()).toJSONString(), IdentityVerifyReqVo.class);
        SysHeadVo sysHeadVo = JSON.parseObject(request.getJSONObject(EnumJsonProperty.REQ_SYS_HEAD.toString()).toJSONString(), SysHeadVo.class);

        // 检查请求报文各个字段内容是否符合要求
        if (BusiUtil.isNull(identityVerifyReqVo.getChkTp())) {
            errorCode = "EE1019";
        } else if (BusiUtil.isNotEquals(identityVerifyReqVo.getChkTp(), "1") && BusiUtil.isNotEquals(identityVerifyReqVo.getChkTp(), "2")) {
            errorCode = "EE1020";
        } else if (BusiUtil.isNull(identityVerifyReqVo.getName())) {
            errorCode = "EE1021";
        } else if (BusiUtil.isNull(identityVerifyReqVo.getCrdtNo())) {
            errorCode = "EE1022";
        } else if (BusiUtil.isNull(identityVerifyReqVo.getCrdtTp())) {
            errorCode = "EE1023";
        } else if (BusiUtil.isNull(identityVerifyReqVo.getNat())) {
            errorCode = "EE1024";
        }

        // 报文内容错误
        if (BusiUtil.isNotNull(errorCode)) {
            result = new Result(EnumResultType.SUCCESS.getStatusCode(), EnumResultType.SUCCESS.getMsg());
            identityVerifyResVo.setChkRes(ErrorUtil.getErrorDesc(errorCode));
            identityVerifyResVo.setChkMsg(errorCode);
            result.setData(identityVerifyResVo);
            return result;
        }

        switch (identityVerifyReqVo.getChkTp()) {
            case "1":
                //todo:查询公共服务平台边民备案核验
                result = peopleIdentityVerify(identityVerifyReqVo, sysHeadVo);
                break;
            case "2":
                //todo:查询市场交易平台商铺备案核验
                result = merchantIdentityVerify(identityVerifyReqVo, sysHeadVo);
                break;
            default:
                //todo:报错
                throw ExceptionUtil.businessException("EE4013");
        }
        log.info("银行核验边民商铺备案查询返回报文: " + JSON.toJSONString(result));
        return result;
    }

    private Result peopleIdentityVerify(IdentityVerifyReqVo identityVerifyReqVo, SysHeadVo sysHeadVo) {
        Map<String, String> requestHeaders = new HashMap<String, String>();
        IdentityVerifyResVo identityVerifyResVo = new IdentityVerifyResVo();
        // 复制发送报文
        BeanUtils.copyProperties(identityVerifyReqVo, identityVerifyResVo);
        // 公共服务平台发送报文发送header部分
        requestHeaders.put("clientId", keyPropertiesVo.getClientId());
        requestHeaders.put("requestId", UUID.randomUUID().toString());
        requestHeaders.put("requestTime", DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));

        JSONObject json = new JSONObject();
        json.put("idcard", identityVerifyReqVo.getCrdtNo());
        log.info("公共服务平台边民备案查询请求流水：" + requestHeaders.get("requestId"));
        log.info("公共服务平台边民备案查询请求明文：" + json.toJSONString());
        TOrgUrlManage orgUrlManage = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(EnumBranch.GGFWPT.toString(), EnumOrgType.OTHER.toString(), EnumBranch.COMMON.toString());
        String afterEncrypt = signHandler.encrypt(json.toString(), orgUrlManage.getPubCert());
        log.info("公共服务平台边民备案查询请求密文：" + afterEncrypt);

        //接口推送
        String response = "";
        String responseEncryptJson = "";  //返回加密报文
        JSONObject responseDecryptJson = new JSONObject();  //解密后报文
        try {
            // 先解析，看看返回值是否是json
            response = okHttpUtil.doPostJson(orgUrlManage.getInterfaceUrl(), afterEncrypt, requestHeaders);
            responseDecryptJson = JSON.parseObject(response);
            log.info("公共服务平台响应报文（解密前）: " + response);
        } catch (Exception e) {
            // 解析失败，说明返回的是base64字符串，需要解密
            responseEncryptJson = signHandler.decrypt(response);
            log.info("公共服务平台响应报文(解密后): " + responseEncryptJson);
            responseDecryptJson = JSON.parseObject(responseEncryptJson);
        }

        // 公共服务平台返回：200备案有效、300 未备案、400备案已过期、500其他错误
        // 返回值转换，返回银行：1-已备案，2-未备案
        if (BusiUtil.isEquals("200", responseDecryptJson.getString("errcode"))) {
            identityVerifyResVo.setChkRes("1");
        } else {
            identityVerifyResVo.setChkRes("2");
        }
        identityVerifyResVo.setChkMsg(responseDecryptJson.getString("message"));

        //保存银行查询边民备案信息
        try {
            log.info("保存银行查询边民备案信息");
            TIdentityVerify identityVerify = new TIdentityVerify();
            identityVerify.setLogId(MDC.get("lodId"));
            identityVerify.setBankId(sysHeadVo.getBankId());
            identityVerify.setOrgCode(sysHeadVo.getOrgCode());
            identityVerify.setVerifyType(identityVerifyReqVo.getChkTp());
            identityVerify.setName(identityVerifyReqVo.getName());
            identityVerify.setCardType(identityVerifyReqVo.getCrdtTp());
            identityVerify.setCardNo(identityVerifyReqVo.getCrdtNo());
            identityVerify.setNat(identityVerifyReqVo.getNat());
            identityVerify.setRequestTime(DateUtil.getCurrentLocalDateTime());
            identityVerify.setOrgCode("");
            identityVerify.setResponseCode(responseDecryptJson.getString("errcode"));
            identityVerify.setResponseLog(responseDecryptJson.getString("message"));
            identityVerifyService.save(identityVerify);
        } catch (Exception e) {
            log.info("保存银行查询边民备案信息失败: " + e.getMessage());
        }

        // 返回报文
        Result result = new Result(EnumResultType.SUCCESS.getStatusCode(), EnumResultType.SUCCESS.getMsg());
        result.setData(identityVerifyResVo);
        return result;
    }

    /**
     * 查询商铺备案信息
     */
    private Result merchantIdentityVerify(IdentityVerifyReqVo identityVerifyReqVo, SysHeadVo sysHeadVo) {
        //组装发送公共交易中心报文
        CommonSendVo<Object> commonSendVo = new CommonSendVo<>();
        sysHeadVo.setServiceCode(EnumServiceCode.PLAT_MP0001.toString());
        CommonHeadSendVo commonHeadSendVo = new CommonHeadSendVo();
        BeanUtils.copyProperties(sysHeadVo, commonHeadSendVo);
        commonSendVo.setCommonHeadSendVo(commonHeadSendVo);
        commonSendVo.setBody(identityVerifyReqVo);
        log.info("互联互通转发商铺备案核验请求明文: " + JSON.toJSONString(commonSendVo));

        //根据机构查询配置表获取URL，通用默认一个机构只有一个URL
        TOrgUrlManage orgUrlManage = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(sysHeadVo.getOrgCode(), EnumOrgType.OTHER.toString(), EnumServiceCode.PLAT_MP0001.toString());
        String afterEncrypt = signHandler.encrypt(JSON.toJSONString(identityVerifyReqVo), orgUrlManage.getPubCert());
        commonSendVo.setBody(afterEncrypt);
        Map<String, String> requestHeaders = okHttpUtil.getRequestHeaders(orgUrlManage.getAppKey(), orgUrlManage.getInterfaceUrl(), commonHeadSendVo.getBankId());
        log.info("互联互通转发商铺备案核验请求密文：" + JSON.toJSONString(commonSendVo));

        //接口推送
        String responseEncryptJson = "";  //返回加密报文
        JSONObject responseDecryptJson = new JSONObject();  //解密后报文
        try {
            // 先解析返回报文
            responseEncryptJson = okHttpUtil.doPostJson(orgUrlManage.getInterfaceUrl(), JSON.toJSONString(commonSendVo), requestHeaders);
            responseDecryptJson = JSON.parseObject(responseEncryptJson);
            log.info("商铺备案验证查询响应报文(解密前): " + JSON.toJSONString(responseDecryptJson));
            String date = responseDecryptJson.getString(EnumJsonProperty.RES_DATA.toString());
            // 解密DATA部分
            if (BusiUtil.isNotNull(date)) {
                responseDecryptJson.put(EnumJsonProperty.RES_DATA.toString(), JSONObject.parseObject(signHandler.decrypt(date)));
            }
            log.info("商铺备案验证查询响应报文(解密后): " + JSON.toJSONString(responseDecryptJson));
        } catch (Exception e) {
            log.info("商铺备案验证查询响应报文解析失败: " + e.getMessage());
        }

        //保存银行查询商铺备案信息
        try {
            log.info("保存银行查询商铺备案信息");
            TIdentityVerify identityVerify = new TIdentityVerify();
            identityVerify.setVerifyType(identityVerifyReqVo.getChkTp());
            identityVerify.setName(identityVerifyReqVo.getName());
            identityVerify.setCardType(identityVerifyReqVo.getCrdtTp());
            identityVerify.setCardNo(identityVerifyReqVo.getCrdtNo());
            identityVerify.setNat(identityVerifyReqVo.getNat());
            identityVerify.setRequestTime(DateUtil.getCurrentLocalDateTime());
            identityVerify.setOrgCode(sysHeadVo.getOrgCode());
            identityVerify.setResponseCode(responseDecryptJson.getJSONObject(EnumJsonProperty.RES_DATA.toString()).getString("ChkRes"));
            identityVerify.setResponseLog(responseDecryptJson.getJSONObject(EnumJsonProperty.RES_DATA.toString()).getString("ChkMsg"));
            identityVerifyService.save(identityVerify);
        } catch (Exception e) {
            log.info("保存银行查询商铺备案信息失败: " + e.getMessage());
        }

        // 返回报文
        Result result = new Result(responseDecryptJson.getString(EnumJsonProperty.RES_STATUS_CODE.toString()), responseDecryptJson.getString(EnumJsonProperty.RES_STATUS_MSG.toString()));
        result.setData(responseDecryptJson.getJSONObject(EnumJsonProperty.RES_DATA.toString()));
        return result;
    }
}
